From ede40297a7646896c3e797b5621ec31c90c2a02e Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Wed, 16 Aug 2006 10:21:13 -0600 Subject: [PATCH] [IA64] resolve VTI address wrap issue This patch resolves the address wrap issue in vtlb_purge and vhpt_purge Signed-off-by: Anthony Xu --- xen/arch/ia64/vmx/vtlb.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/xen/arch/ia64/vmx/vtlb.c b/xen/arch/ia64/vmx/vtlb.c index 1fffd1366d..8d2da7f308 100644 --- a/xen/arch/ia64/vmx/vtlb.c +++ b/xen/arch/ia64/vmx/vtlb.c @@ -245,7 +245,6 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) return ret; } - /* * purge software guest tlb */ @@ -253,29 +252,29 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) void vtlb_purge(VCPU *v, u64 va, u64 ps) { thash_data_t *cur; - u64 start, end, curadr, size, psbits, tag, def_size; + u64 start, curadr, size, psbits, tag, rr_ps, num; ia64_rr vrr; thash_cb_t *hcb = &v->arch.vtlb; + vcpu_get_rr(v, va, &vrr.rrval); psbits = VMX(v, psbits[(va >> 61)]); - size = PSIZE(ps); - start = va & (-size); - end = start + size; + start = va & ~((1UL << ps) - 1); while (psbits) { curadr = start; - ps = __ffs(psbits); - psbits &= ~(1UL << ps); - def_size = PSIZE(ps); - vrr.ps = ps; - /* Be careful about overflow. */ - while (curadr < end && curadr >= start) { + rr_ps = __ffs(psbits); + psbits &= ~(1UL << rr_ps); + num = 1UL << ((ps < rr_ps) ? 0 : (ps - rr_ps)); + size = PSIZE(rr_ps); + vrr.ps = rr_ps; + while (num) { cur = vsa_thash(hcb->pta, curadr, vrr.rrval, &tag); while (cur) { - if (cur->etag == tag && cur->ps == ps) + if (cur->etag == tag && cur->ps == rr_ps) cur->etag = 1UL << 63; cur = cur->next; } - curadr += def_size; + curadr += size; + num--; } } } @@ -288,14 +287,14 @@ static void vhpt_purge(VCPU *v, u64 va, u64 ps) { //thash_cb_t *hcb = &v->arch.vhpt; thash_data_t *cur; - u64 start, end, size, tag; + u64 start, size, tag, num; ia64_rr rr; - size = PSIZE(ps); - start = va & (-size); - end = start + size; - rr.rrval = ia64_get_rr(va); - size = PSIZE(rr.ps); - while(start < end){ + + start = va & ~((1UL << ps) - 1); + rr.rrval = ia64_get_rr(va); + size = PSIZE(rr.ps); + num = 1UL << ((ps < rr.ps) ? 0 : (ps - rr.ps)); + while (num) { cur = (thash_data_t *)ia64_thash(start); tag = ia64_ttag(start); while (cur) { @@ -304,6 +303,7 @@ static void vhpt_purge(VCPU *v, u64 va, u64 ps) cur = cur->next; } start += size; + num--; } machine_tlb_purge(va, ps); } -- 2.30.2